﻿/*
 *  jHandle
 *  http://code.google.com/p/jhandle/
 *
 */

;(function($){

    $.extend({
    
        __handlers: {},
    
	    /*
		
			handle(selector, function)
			--------------------------
			Adds a handler to items matched by selector
			
			handle(selector, function, function)
			------------------------------------
			Adds a handler and an unhandler to the items matched by selector
			
			handle(selector, function, object)
			----------------------------------
			Adds a handler to items matched by selector and changes the 
			behaviour with the specified options object
			
			handle(selector, function, function, object)
			--------------------------------------------
			Adds a handler and unhandler to items matched by selector with
			behaviour specified with the options object
			
		*/
		handle: function()
		{
            
            // get the arguments
            var a = arguments;
            
            // prepare the object for the cache
            var obj = {
                selector: a[0],
                handler: a[1]
            };

            // handle the third and fourth
            if (a.length > 2)
            {
                // is the third parameter a function or an object?
                if ($.isFunction(a[2]))
                {
                
                    // the third parameter is a function and therefore our unhandler
                    obj.unhandler = a[2];
                    
                    // do we have options too?
                    if (a.length > 3)
                        // merge the options
                        $.extend(obj, a[3]);
                        
                }
                else
                    // our options are the third parameter
                    $.extend(obj, a[2]);
            }
            
            // make sure the cache has an array for our selector
            this.__handlers[obj.selector] = this.__handlers[obj.selector] || [];
            
            // add this handler to the array of handlers for this selector
            this.__handlers[obj.selector].push( obj );
            
            // find elements that match this selector
            var elements = $(obj.selector);
            
            // handle the matched elements
            this.__handleElements(elements, obj.handler);
            
		},
		
		// executes the handler on the specified elements
		__handleElements: function(elements, handler)
		{
		    // loop through the elements
		    for (var i = 0, l = elements.length; i < l; i++)
		    {
		        // get this element
		        var el = elements[i];
		        
		        // set the handler
		        el.executingHandler = handler;
		        
		        // execute the handler
		        el.executingHandler({
		            index: i
		        });
		        
		        // delete the handler reference
		        delete el.executingHandler;
		        
		    }
		}
    
    });
	
	$.fn.extend({
	
	    /*
	    
	        handle()
	        --------
	        Checks the currently selected elements for any that match any of the
	        cached handlers and executes them.
	        
	    */
	    handle: function(){
	    
	        var jthis = this;
	        
	        // loop through the handlers
	        $.each($.__handlers, function(k,v){
	            
	            // find matching elements 
                var els = jthis.find(k);
                
                // loop through each handler for these elements
                $(v).each(function(hkey, hval){
                    $.__executeHandler(els, hval.handler);
                });
	            
	        });
	    
            // TODO: check the selected elements and all children (see $().find method)
            // to see if any of the cached handlers ($.__handlers) match - and then
            // execute the handler on these elements (using $.__handleElements)
	    
	    }
		
	})
	
})( jQuery );